package world.snowcrystal.model.dto.post;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import world.snowcrystal.model.entity.Post;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Document(indexName = "posts")
@Accessors(chain = true)
@Data
public class PostEsDTO implements Serializable {

    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
    //        2024-10-10 15:11:15
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * Es 文档 id ，在添加数据到 Es 时必须显示指定了这个字段，
     * es 生成的字段为字符串，类型转换时将产生异常
     */
    @Id
    private Long id;

    /**
     * 标题
     */
    private String title;

    /**
     * 内容
     */
    private String content;

    /**
     * 标签列表
     */
    private List<String> tags;

    /**
     * 创建用户 id
     */
    private Long userId;

    /**
     * 创建时间
     */
    @Field(index = false, store = true, type = FieldType.Date, format = {}, pattern = DATE_TIME_PATTERN)
    private Date createTime;

    /**
     * 更新时间
     */
    @Field(index = false, store = true, type = FieldType.Date, format = {}, pattern = DATE_TIME_PATTERN)
    private Date updateTime;

    /**
     * 是否删除
     */
    private Integer isDelete;

    private static final long serialVersionUID = 1L;

    private static final Gson GSON = new Gson();

    /**
     * 对象转包装类
     *
     * @param post
     * @return
     */
    public static PostEsDTO objToDto(Post post) {
        if (post == null) {
            return null;
        }
        PostEsDTO postEsDTO = new PostEsDTO();
        BeanUtils.copyProperties(post, postEsDTO);
        String tagsStr = post.getTags();
        if (StringUtils.isNotBlank(tagsStr)) {
            postEsDTO.setTags(GSON.fromJson(tagsStr, new TypeToken<List<String>>() {
            }.getType()));
        }
        return postEsDTO;
    }

    public static Post dtoToObj(PostEsDTO postEsDTO) {
        if (postEsDTO == null) {
            return null;
        }
        Post post = new Post();
        BeanUtils.copyProperties(postEsDTO, post);
        List<String> tagList = postEsDTO.getTags();
        if (CollectionUtils.isNotEmpty(tagList)) {
            post.setTags(GSON.toJson(tagList));
        }
        return post;
    }


    public PostEsDTO setTags(List<String> tags) {
        this.tags = tags;
        return this;
    }

    public PostEsDTO setContent(String content) {
        this.content = content;
        return this;
    }

    public PostEsDTO setTitle(String title) {
        this.title = title;
        return this;
    }

    public PostEsDTO setIdStrategy(String id) {
        this.id = Long.parseLong(id);
        return this;
    }

    public PostEsDTO setIsDeleteStrategy(String isDelete) {
        this.isDelete = Integer.parseInt(isDelete);
        return this;
    }

    @SneakyThrows
    public PostEsDTO setUpdateTimeStrategy(String updateTime) {
        this.updateTime = sdf.parse(updateTime);
        return this;
    }

    @SneakyThrows
    public PostEsDTO setCreateTimeStrategy(String createTime) {
        this.createTime = sdf.parse(createTime);
        return this;
    }

    public PostEsDTO setUserIdStrategy(String userId) {
        this.userId = Long.parseLong(userId);
        return this;
    }

    public PostEsDTO setTagsStrategy(String tags) {
        this.tags = Arrays.asList(tags.split(","));
        return this;
    }

}
